/*!
    \copyright  Copyright (c) 2024 Qualcomm Technologies International, Ltd.
                All Rights Reserved.
                Qualcomm Technologies International, Ltd. Confidential and Proprietary.
    \file
    \ingroup    gmap_profile
    \brief      Initializes the GMAS server and common placeholder for Broadcast/Unicast for GMAP
*/
#ifdef ENABLE_GMAP_PROFILE
#include "gatt_gmas_server.h"
#include "gmap_profile.h"
#include "gatt_connect.h"
#include "gatt_service_discovery.h"
#include "gmap_server_role_advertising.h"
#include <gatt_handler_db_if.h>

#include <logging.h>

#define GMAP_PROFILE_LOG            DEBUG_LOG

#ifdef INCLUDE_LE_AUDIO_UNICAST
#define GMAP_UNICAST_SINK_ROLE      GMAS_ROLE_UNICAST_GAME_TERMINAL
#else
#define GMAP_UNICAST_SINK_ROLE      0
#endif

#ifdef INCLUDE_LE_AUDIO_BROADCAST
#define GMAP_BROADCAST_SINK_ROLE    GMAS_ROLE_BROADCAST_GAME_RECEIVER
#else
#define GMAP_BROADCAST_SINK_ROLE    0
#endif

#define GMAP_PROFILE_ROLE           (GMAP_UNICAST_SINK_ROLE | GMAP_BROADCAST_SINK_ROLE)

#if defined(INCLUDE_LE_AUDIO_UNICAST)
#define GMAP_SERVER_HANDLE_START    HANDLE_GAMING_AUDIO_SERVICE
#define GMAP_SERVER_HANDLE_END      HANDLE_GAMING_AUDIO_SERVICE_END
#else
#define GMAP_SERVER_HANDLE_START    0xFFFF
#define GMAP_SERVER_HANDLE_END      0xFFFF
#endif

/* Service handle initialization failure */
#define GMAP_INVALID_SERVICE_HANDLE      ((ServiceHandle)(0x0000))

static void gmapProfile_OnGattConnect(gatt_cid_t cid);
static void gmapProfile_OnGattDisconnect(gatt_cid_t cid);
static void gmapProfile_OnEncryptionChanged(gatt_cid_t cid, bool encrypted);

static ServiceHandle gmasServiceHandle = GMAP_INVALID_SERVICE_HANDLE;
static TaskData gmap_profile_task;

static const gatt_connect_observer_callback_t gmapProfile_connect_callbacks =
{
    .OnConnection = gmapProfile_OnGattConnect,
    .OnDisconnection = gmapProfile_OnGattDisconnect,
    .OnEncryptionChanged = gmapProfile_OnEncryptionChanged
};

static void gmapProfile_OnGattConnect(gatt_cid_t cid)
{
    UNUSED(cid);
}

static void gmapProfile_OnGattDisconnect(gatt_cid_t cid)
{
    if (gmasServiceHandle != GMAP_INVALID_SERVICE_HANDLE)
    {
        GattGmasServerRemoveConfig(gmasServiceHandle, cid);
    }
}

static void gmapProfile_OnEncryptionChanged(gatt_cid_t cid, bool encrypted)
{
    if (encrypted && !GattConnect_IsDeviceTypeOfPeer(cid) && gmasServiceHandle != GMAP_INVALID_SERVICE_HANDLE)
    {
        GattGmasServerAddConfig(gmasServiceHandle, cid);
    }
}

static void gmapProfile_MessageHandler(Task task, MessageId id, Message message)
{
    UNUSED(id);
    UNUSED(task);
    UNUSED(message);
}

void GmapProfile_Init(void)
{
    GattGmasInitData initData;

    gmap_profile_task.handler = gmapProfile_MessageHandler;

    if (gmasServiceHandle == GMAP_INVALID_SERVICE_HANDLE)
    {
        GMAP_PROFILE_LOG("GmapProfile_Init");
        initData.role = GMAP_PROFILE_ROLE;
        initData.ugtFeatures = (GMAS_UGT_SOURCE_FEATURE_SUPPORT | GMAS_UGT_80KBPS_SOURCE_FEATURE_SUPPORT | GMAS_UGT_SINK_FEATURE_SUPPORT |
                                GMAS_UGT_64KBPS_SINK_FEATURE_SUPPORT | GMAS_UGT_MULTIPLEX_FEATURE_SUPPORT | GMAS_UGT_MULTISINK_FEATURE_SUPPORT |
                                GMAS_UGT_MULTISOURCE_FEATURE_SUPPORT);
#ifdef INCLUDE_LE_AUDIO_BROADCAST
        initData.bgrFeatures = (GMAS_BGR_MULTISINK_FEATURE_SUPPORT | GMAS_BGR_MULTIFRAME_FEATURE_SUPPORT);
#endif
        gmasServiceHandle = GattGmasServerInit(TrapToOxygenTask((Task)&gmap_profile_task),
                                               GMAP_SERVER_HANDLE_START,
                                               GMAP_SERVER_HANDLE_END,
                                               &initData);

        GattConnect_RegisterObserver(&gmapProfile_connect_callbacks);
        GattServiceDiscovery_RegisterServiceForDiscovery(GATT_SD_GMAS_SRVC);
    }

    GmapServer_SetupLeAdvertisingData();
}

#endif /* ENABLE_GMAP_PROFILE */
